Async Generatorを外部から中断する
例:10回だけ#text-inputのeventを取得するscript
code:test-exec.js
import {listenInput} from "./test.js";
(async () => {
let count = 0;
for await (const event of listenInput()) {
count++;
if (count > 10) break;
console.log(event);
}
})();
code:test.js
const textInput = document.getElementById("text-input");
function getPromise() {
let _resolve;
const update = () => new Promise((res) => _resolve = res);
const resolve = (value) => _resolve?.(value);
}
export async function* listenInput() {
const callback = e => resolve(e);
textInput.addEventListener("input", callback);
try {
console.log("Start iteration"); // for debug
while (true) {
yield await waitEventFired();
}
} finally {
// 後始末
console.log("End iteration"); // for debug
textInput.removeEventListener("input", callback);
}
}
他にもこのやり方をやっている人がいるかは調べていないみた
そこそこ見つかった
ていうかNode.jsの標準ライブラリにあるんかい!
for awaitループを処理している間に発火したeventは全て捨てられる
次のループに入るまで、resolveが更新されない
更新前、つまり解決済みのPromiseのresolveを何度呼び出してもなにも起きない
eventを捨てないパターンも作りたいなtakker.icon
2021-10-13
15:21:52 函数をundefinedで呼び出す可能性のある部分が合ったので修正
10:59:26 名前変更
s/update/waitEventFired
10:57:29 ↓で問題なさそうだったので直した
指摘されたとおり、↓でいいのでは?
code:diff
while (true) {
- const event = await done;
- done = update();
- yield event;
+ yield await update();
}
なんでこうしなかったんだっけ?takker.icon
update()を待ってもすぐにresolveしないから?
いやいやそれでいいんだよtakker.icon
event listenerが発火するまで待つんだから
Related to